Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

1letter/fix#671 #675

Merged
merged 11 commits into from
Oct 23, 2023
Merged

1letter/fix#671 #675

merged 11 commits into from
Oct 23, 2023

Conversation

1letter
Copy link
Contributor

@1letter 1letter commented Oct 19, 2023

Fix for #671

better constructing of the url, use explicit the portal url

@mister-roboto
Copy link

@1letter thanks for creating this Pull Request and helping to improve Plone!

TL;DR: Finish pushing changes, pass all other checks, then paste a comment:

@jenkins-plone-org please run jobs

To ensure that these changes do not break other parts of Plone, the Plone test suite matrix needs to pass, but it takes 30-60 min. Other CI checks are usually much faster and the Plone Jenkins resources are limited, so when done pushing changes and all other checks pass either start all Jenkins PR jobs yourself, or simply add the comment above in this PR to start all the jobs automatically.

Happy hacking!

@1letter
Copy link
Contributor Author

1letter commented Oct 19, 2023

@jenkins-plone-org please run jobs

(self.context, self.request), name="plone_portal_state"
)
portal_url = portal_state.portal_url()

if obj:
url = "/".join(obj.getPhysicalPath()[2:])
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I might be wrong, but if this [:2] is to remove something like "/app/Plone", then it is not valid...
You can have Plone site inside other objects, e.g. a Folder.
e.g. the path might be /app/folder/Plone or /app/folder/subfolder/Plone.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@ale-rt right, i will refactor this

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Consider also VHM rules, and the use of _vh_ (for example:

    location /zope {
        proxy_pass http://localhost:8080/VirtualHostBase/https/site.com/VirtualHostRoot/_vh_zope;
    }

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

using absolute_url() will do it.

@pbauer
Copy link
Member

pbauer commented Oct 19, 2023

Stupid question: Why not simply use obj.absolute_url() for all of that?

@yurj
Copy link
Contributor

yurj commented Oct 19, 2023

Stupid question: Why not simply use obj.absolute_url() for all of that?

The uid will resolve to a catalog path. There's already a call in Zope to resolve from a catalog path to the object:
https://github.com/zopefoundation/Zope/blob/29e088e04db9feb9f5d3bc6bea8950d98f8283a1/src/ZPublisher/HTTPRequest.py#L244

so I think we just simply need to use this Zope function.

Looking better, I was wrong. The uid is resolved to the object itself, so you're plain right.

url = "/".join(obj.getPhysicalPath()[2:])
if not url.startswith("/"):
url = "/" + url
url = obj.absolute_url()
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd check for obj first (keep the if from line 114) ... it might be that the uuid is missing.

Copy link
Contributor

@yurj yurj Oct 19, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

also uid = url.split("/")[-1] above is fragile ("/resolveuid/" vs "resolveuid/" vs "/a/relativepath/resolveuid"). Generally, you should find the index of 'resolveuid' in the path, and get the next one if it exists. It should be something like this (uid = getuid(path)):

def get_uid(path):
    paths = path.split('/')
    uid = None
    if 'resolveuid' in paths:
        ri = paths.index('resolveuid')
        if ri + 1 != len(paths):
            uid = paths[ri + 1]
            if uid == '':
               uid = None
    return uid 
>>> get_uid('gfdgdf')
>>> get_uid('')
>>> get_uid('/resolveuid/')
>>> get_uid('/resolveuidgfdgd/')
>>> get_uid('/resolveuid/4342432')
'4342432'
>>> get_uid('/resolveuid/4342432/')
'4342432'
>>> get_uid('fdsfd/fdf/resolveuid/4342432/')
'4342432'
>>> get_uid('/fdsfd/fdf/resolveuid/4342432/')
'4342432'
>>> 

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

is resolve[uU]id still a thing?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@petschki maybe, but i'm not sure

Copy link
Member

@petschki petschki Oct 20, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

def get_uid(path):
    paths = path.split('/')
    uid = None
    if 'resolveuid' in paths:
        ri = paths.index('resolveuid')
        if ri + 1 != len(paths):
            uid = paths[ri + 1]
            if '#' in uid:
                uid = uid.split('#')[0]
            if uid == '':
               uid = None
    return uid 
>>> get_uid('gfdgdf')
>>> get_uid('')
>>> get_uid('/resolveuid/')
>>> get_uid('/resolveuidgfdgd/')
>>> get_uid('/resolveuid/4342432')
'4342432'
>>> get_uid('/resolveuid/4342432/')
'4342432'
>>> get_uid('fdsfd/fdf/resolveuid/4342432/')
'4342432'
>>> get_uid('/fdsfd/fdf/resolveuid/4342432/')
'4342432'
>>> get_uid('/resolveuid/fb91bddde7eb46efbed20e9c10fb4929#autotoc-item-autotoc-1')
'fb91bddde7eb46efbed20e9c10fb4929'
>>> 

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@1letter solution to use urlparse is very good! Question: uid's are all lowercase? What if an UID has uppercase letters?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

At least plone.outputfilters still takes it into account: https://github.com/plone/plone.outputfilters/blob/master/plone/outputfilters/filters/resolveuid_and_caption.py#L31

https://github.com/plone/plone.outputfilters/blob/278e2752c4790b5af2470bfc3c91a8aa26a9a80f/plone/outputfilters/filters/resolveuid_and_caption.py#L130

here is what plone.output filter does. It uses the re above to get all parts of the url. If there's an uid, find the object, translate it to the absolute_url, add the other parts.

If we want to do this the same way outputfilter does, we should use this code. This code also check IResolveUidsEnabler. Maybe this last part is not important (if a site disable uids and use resolveuid as a folder name...).

Generally, resoulveuid and catalog path resolution should be done in one place, I think in plone.api. I don't know about circular dipendencies...

Anyway, the actual code is ok, should works as expected and it is a real improvement.

@yurj
Copy link
Contributor

yurj commented Oct 19, 2023

absolute_url()

BTW, absolute_url() uses physicalPathToVirtualPath:

https://github.com/zopefoundation/Zope/blob/29e088e04db9feb9f5d3bc6bea8950d98f8283a1/src/OFS/Traversable.py#L51 (absolute_url() -> self.virtual_url_path())
https://github.com/zopefoundation/Zope/blob/29e088e04db9feb9f5d3bc6bea8950d98f8283a1/src/OFS/Traversable.py#L102C50-L102C75 (self.virtual_url_path() -> physicalPathToVirtualPath)

@1letter 1letter marked this pull request as draft October 20, 2023 06:40
- Make resolution of uid more robust
- calculate a fragment of anchor if available
@1letter 1letter marked this pull request as ready for review October 20, 2023 09:52
Copy link
Contributor

@yurj yurj left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

At least plone.outputfilters still takes it into account: https://github.com/plone/plone.outputfilters/blob/master/plone/outputfilters/filters/resolveuid_and_caption.py#L31

https://github.com/plone/plone.outputfilters/blob/278e2752c4790b5af2470bfc3c91a8aa26a9a80f/plone/outputfilters/filters/resolveuid_and_caption.py#L130

here is what plone.output filter does. It uses the re above to get all parts of the url. If there's an uid, find the object, translate it to the absolute_url, add the other parts.

If we want to do this the same way outputfilter does, we should use this code. This code also check IResolveUidsEnabler. Maybe this last part is not important (if a site disable uids and use resolveuid as a folder name...).

Generally, resoulveuid and catalog path resolution should be done in one place, I think in plone.api. I don't know about circular dipendencies...

Anyway, the actual code is ok, should works as expected and it is a real improvement.

url = "/".join(obj.getPhysicalPath()[2:])
if not url.startswith("/"):
url = "/" + url
url = obj.absolute_url()
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

At least plone.outputfilters still takes it into account: https://github.com/plone/plone.outputfilters/blob/master/plone/outputfilters/filters/resolveuid_and_caption.py#L31

https://github.com/plone/plone.outputfilters/blob/278e2752c4790b5af2470bfc3c91a8aa26a9a80f/plone/outputfilters/filters/resolveuid_and_caption.py#L130

here is what plone.output filter does. It uses the re above to get all parts of the url. If there's an uid, find the object, translate it to the absolute_url, add the other parts.

If we want to do this the same way outputfilter does, we should use this code. This code also check IResolveUidsEnabler. Maybe this last part is not important (if a site disable uids and use resolveuid as a folder name...).

Generally, resoulveuid and catalog path resolution should be done in one place, I think in plone.api. I don't know about circular dipendencies...

Anyway, the actual code is ok, should works as expected and it is a real improvement.

add empty line at the end of news file
@1letter
Copy link
Contributor Author

1letter commented Oct 20, 2023

@jenkins-plone-org please run jobs

Copy link
Member

@pbauer pbauer left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

@1letter
Copy link
Contributor Author

1letter commented Oct 23, 2023

@1letter 1letter merged commit 5907233 into master Oct 23, 2023
13 checks passed
@1letter 1letter deleted the 1letter/fix#671 branch October 23, 2023 11:40
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants